// SPDX-License-Identifier: LGPL-3.0-or-later
#include <gtest/gtest.h>

#include <iostream>
#include <vector>

#include "device.h"
#include "tabulate.h"
#include "utilities.h"

class TestTabulateSeR : public ::testing::Test {
 protected:
  // em_x = tf.random.uniform([4, 16], minval=0, maxval=0.2, dtype = tf.float64)
  std::vector<double> info = {0, 0.2, 0.4, 0.01, 0.1, -1};
  std::vector<double> em = {0.0343909,  0.11357423, 0.0858676,  0.19337772,
                            0.1935728,  0.0477744,  0.05845198, 0.19080509,
                            0.16111261, 0.07179262, 0.10078013, 0.04640909,
                            0.10433399, 0.15650861, 0.17527857, 0.04249097};

  std::vector<double> table = {
      6.348551343037398542e-01,  4.209465843706336474e-04,
      6.390862740714405368e-03,  -1.544448595628262176e-04,
      -1.891095227974180087e-04, 2.695025951562175852e-05,
      -1.317549846042939343e+00, -5.624478206903206490e-02,
      1.274284553146523905e-02,  -6.836227424141475689e-04,
      -1.438066096020836407e-04, -1.854932873974712940e-06,
      -9.996964112615246423e-01, 6.928234423723647617e-02,
      -4.974719973810486084e-03, -2.019584729176823030e-04,
      1.077254539742680247e-04,  -8.024209768588029797e-06,
      3.552689563657350780e-01,  -3.578299775339799371e-02,
      -1.319946251007718743e-03, 1.016701374495701440e-03,
      -1.057336720791906388e-04, 5.182678943855506567e-06,
      1.227750369557627286e+00,  4.100352079064395472e-02,
      3.586869164810712295e-03,  -4.304540913340443135e-04,
      -1.269943482892440004e-04, 1.459465404430219674e-05,
      -1.472642501673147031e+00, -1.611354921283318364e-01,
      1.645427874390196360e-02,  2.107392978135091402e-04,
      -2.193541011180757461e-04, 1.915392497459551146e-05,
      -2.855174490181606739e-01, 9.774337856626263976e-02,
      -2.140891880666230714e-03, -7.148328890055103638e-04,
      1.965696332267534503e-05,  -4.593489654121371453e-06,
      -1.468441009949382314e+00, -6.360828127262234399e-02,
      4.751283295356955282e-03,  8.711899561753186068e-05,
      -9.937008678852959884e-06, 4.273569346584811685e-07,
      6.348599826995243722e-01,  5.487167506364742930e-04,
      6.386116198716365253e-03,  -1.619832375568118791e-04,
      -1.877328309473502049e-04, 2.134130914519164856e-05,
      -1.318111020264137512e+00, -5.599013082054477008e-02,
      1.272225054666903735e-02,  -6.893710047488201898e-04,
      -1.434367581078517366e-04, 3.329508890614227371e-05,
      -9.990040854920316793e-01, 6.918278968071900348e-02,
      -4.980714172967731085e-03, -1.976574487947816198e-04,
      1.070037204086153902e-04,  -7.859875077388093586e-06,
      3.549109954092205532e-01,  -3.580909209068139365e-02,
      -1.289508598157979719e-03, 1.012474257117017967e-03,
      -1.054418924402112718e-04, -1.245498322204730900e-05,
      1.228160763020727630e+00,  4.107512853046493134e-02,
      3.573879491390910459e-03,  -4.355190226638688713e-04,
      -1.258433981470396103e-04, 1.610862268100766631e-05,
      -1.474252210958008291e+00, -1.608063442081248406e-01,
      1.646046950167207382e-02,  2.019843636566674109e-04,
      -2.185756589083626730e-04, 1.978479879983412190e-05,
      -2.845402300363228942e-01, 9.770034635718018168e-02,
      -2.162325119197382531e-03, -7.140472215558940627e-04,
      1.956302663031799223e-05,  1.932584474244053378e-05,
      -1.469076617546759334e+00, -6.351322951074317436e-02,
      4.753890907276497185e-03,  8.672114560243554321e-05,
      -1.004574434175897967e-05, -4.345700882560937596e-06,
      6.348661083147921769e-01,  6.763897297752743953e-04,
      6.381144275303845745e-03,  -1.694690463885140694e-04,
      -1.868179426353836598e-04, 3.439291082765030046e-05,
      -1.318669650038090335e+00, -5.573589319299507294e-02,
      1.270148368741391351e-02,  -6.950749719342792137e-04,
      -1.422194703304518733e-04, 3.454751241752252323e-05,
      -9.983127558632299836e-01, 6.908311652764687061e-02,
      -4.986579772806746212e-03, -1.933888092529071571e-04,
      1.068327546750306073e-04,  -2.976978385983384886e-05,
      3.545527765488725169e-01,  -3.583457894275744043e-02,
      -1.259197760082061621e-03, 1.008246479193084487e-03,
      -1.059401869200098984e-04, 1.721968053146218465e-06,
      1.228571871257205572e+00,  4.114647496201748883e-02,
      3.560738575723638825e-03,  -4.405332425718102457e-04,
      -1.251648759618972115e-04, 3.659080417076460655e-05,
      -1.475858628153338792e+00, -1.604770750960976822e-01,
      1.646639808472218428e-02,  1.932598402043995316e-04,
      -2.175904819601363058e-04, 1.230256868634094333e-05,
      -2.835634435191126679e-01, 9.765688571984927624e-02,
      -2.183734604613508240e-03, -7.132463811570244078e-04,
      2.021887442373574272e-05,  1.321401495096886281e-05,
      -1.469711274366155784e+00, -6.341812571665436660e-02,
      4.756486470714936521e-03,  8.631384191910702040e-05,
      -1.010516500002806932e-05, -1.110874413279218719e-05,
      6.348735101551836735e-01,  8.039610290153098582e-04,
      6.375948457075718626e-03,  -1.769074132993461279e-04,
      -1.855677150383903214e-04, 3.421271436711027645e-05,
      -1.319225739518145257e+00, -5.548207260888919634e-02,
      1.268054645200545304e-02,  -7.007297564176242621e-04,
      -1.408885818822980523e-04, 3.124701885930576017e-05,
      -9.976224235482542557e-01, 6.898332734138989952e-02,
      -4.992317635216104131e-03, -1.891404922064061889e-04,
      1.053957535708985289e-04,  -1.089286646983666076e-06,
      3.541943058468561834e-01,  -3.585946084769019160e-02,
      -1.229013912637771933e-03, 1.004009466262262241e-03,
      -1.059129033455631863e-04, -4.941663399086282537e-06,
      1.228983691638902087e+00,  4.121755707472917613e-02,
      3.547447845420277635e-03,  -4.455036207721562607e-04,
      -1.239172256532283074e-04, 3.437341080261359686e-05,
      -1.477461752073406132e+00, -1.601476900261984693e-01,
      1.647206544856073471e-02,  1.845724864086241608e-04,
      -2.173853638475303177e-04, 3.620505631412716563e-05,
      -2.825870937484175061e-01, 9.761299713537928413e-02,
      -2.205119732548723246e-03, -7.124245958910824846e-04,
      2.074820558303217398e-05,  1.209381466404663338e-05,
      -1.470344979888463577e+00, -6.332297013406351649e-02,
      4.759069711794740656e-03,  8.589935708505183382e-05,
      -1.045842324058424788e-05, -6.134254562752213537e-06,
      6.348821871815598650e-01,  9.314261853726121809e-04,
      6.370530236175125580e-03,  -1.842978984547447257e-04,
      -1.840210089691990327e-04, 2.234897510077387526e-05,
      -1.319779292891724465e+00, -5.522867246076747227e-02,
      1.265944033870337014e-02,  -7.063360380236871801e-04,
      -1.393416734992873119e-04, 1.931167378610719847e-05,
      -9.969330896946905218e-01, 6.888342466806646192e-02,
      -4.997928623431705138e-03, -1.849303524006284602e-04,
      1.053651633995249134e-04,  -2.870133904891753420e-05,
      3.538355893399378616e-01,  -3.588374034700148041e-02,
      -1.198957225773849763e-03, 9.997681359810027708e-04,
      -1.060678155548662341e-04, -4.107776618240329050e-06,
      1.229396221507694564e+00,  4.128837188660083868e-02,
      3.534008730169808672e-03,  -4.504275777948374090e-04,
      -1.224778886969254976e-04, 2.455513266683544498e-05,
      -1.479061581584721008e+00, -1.598181942132129441e-01,
      1.647747255391585064e-02,  1.759082956613747337e-04,
      -2.158335508261176197e-04, 6.406725844410341030e-06,
      -2.816111850012528728e-01, 9.756868109694678826e-02,
      -2.226479900633348240e-03, -7.115823288942964460e-04,
      2.121038517729223415e-05,  1.358027318850170435e-05,
      -1.470977733597038872e+00, -6.322776301216057049e-02,
      4.761640356162846754e-03,  8.547576468445008296e-05,
      -1.081874527005240631e-05, -8.845528475774308509e-07,
      6.348921383103013349e-01,  1.058780765759985421e-03,
      6.364891110105044131e-03,  -1.916363332792569681e-04,
      -1.827768871456785058e-04, 2.275707291847725182e-05,
      -1.320330314380025793e+00, -5.497569611120622923e-02,
      1.263816684562326688e-02,  -7.118908987616576157e-04,
      -1.380182662155302303e-04, 1.630252530406085050e-05,
      -9.962447554247517711e-01, 6.878341103651769428e-02,
      -5.003413601927745452e-03, -1.807403991329658622e-04,
      1.040363362483998831e-04,  -4.422604643727719699e-06,
      3.534766330394523148e-01,  -3.590741998555346121e-02,
      -1.169027863565602274e-03, 9.955202772264954043e-04,
      -1.060447700647724903e-04, -1.021743279826507342e-05,
      1.229809458175783687e+00,  4.135891644424664892e-02,
      3.520422661584679015e-03,  -4.553035794622276055e-04,
      -1.210679214963379874e-04, 1.595827246550979495e-05,
      -1.480658115605847147e+00, -1.594885928526604546e-01,
      1.648262036665308974e-02,  1.672799673730459213e-04,
      -2.148155690753495697e-04, -1.867405535452657550e-06,
      -2.806357215496423363e-01, 9.752393810975558408e-02,
      -2.247814508535729908e-03, -7.107227883497464890e-04,
      2.207595560206285042e-05,  -1.137331983229785190e-06,
      -1.471609534977757372e+00, -6.313250460562676303e-02,
      4.764198129054059844e-03,  8.503999275315992160e-05,
      -1.072692568096017848e-05, -1.373273803695183988e-05,
      6.349033624136081189e-01,  1.186020367092407990e-03,
      6.359032581545111251e-03,  -1.989262833250400370e-04,
      -1.812752661309344573e-04, 1.302837915648187095e-05,
      -1.320878808237722746e+00, -5.472314689282183064e-02,
      1.261672747063919374e-02,  -7.173917679890315846e-04,
      -1.373052781380030543e-04, 3.768455339511444900e-05,
      -9.955574218354472649e-01, 6.868328895828368363e-02,
      -5.008773436308684712e-03, -1.765844799686671349e-04,
      1.034810966435298563e-04,  -1.111176255155353207e-05,
      3.531174429312692320e-01,  -3.593050231143132822e-02,
      -1.139225984250480384e-03, 9.912704081392112714e-04,
      -1.064918174657224404e-04, 2.680738443515978403e-06,
      1.230223398925979650e+00,  4.142918782293085467e-02,
      3.506691073047987512e-03,  -4.601302388532728274e-04,
      -1.198865987378785417e-04, 1.656386182477533959e-05,
      -1.482251353107205460e+00, -1.591588911206925361e-01,
      1.648750985769346228e-02,  1.586901819247656846e-04,
      -2.147074421644348298e-04, 2.641762503224190698e-05,
      -2.796607076604977760e-01, 9.747876869099537933e-02,
      -2.269122958003529523e-03, -7.098388532529275848e-04,
      2.226701915637888804e-05,  1.106237844209756009e-05,
      -1.472240383519069384e+00, -6.303719517464229094e-02,
      4.766742755353862819e-03,  8.459962202271287246e-05,
      -1.132218730142039535e-05, 8.958476322974335592e-07,
      6.349158583197994643e-01,  1.313140616388666637e-03,
      6.352956158169477396e-03,  -2.061601622854974502e-04,
      -1.806298821034440756e-04, 3.770936817966389514e-05,
      -1.321424778752664952e+00, -5.447102810827629538e-02,
      1.259512371128685033e-02,  -7.228490733933210606e-04,
      -1.356407402355522122e-04, 2.099832634320949299e-05,
      -9.948710899987588396e-01, 6.858306092758209571e-02,
      -5.014008993202081696e-03, -1.724573933478598642e-04,
      1.029144894329912032e-04,  -1.738522780636760158e-05,
      3.527580249757622521e-01,  -3.595298987582695727e-02,
      -1.109551740263377793e-03, 9.870126155001155040e-04,
      -1.064931456292656029e-04, -2.059910396978558087e-06,
      1.230638041011988815e+00,  4.149918312660194619e-02,
      3.492815399561766294e-03,  -4.649051157564728157e-04,
      -1.192927614880224277e-04, 4.072077917749542957e-05,
      -1.483841293110880866e+00, -1.588290941739924356e-01,
      1.649214200293154520e-02,  1.501282794678792006e-04,
      -2.138853834118830831e-04, 2.633111784219914963e-05,
      -2.786861475954987011e-01, 9.743317336979973042e-02,
      -2.290404652904617314e-03, -7.089360554728917595e-04,
      2.260180638238835256e-05,  1.741828165826791135e-05,
      -1.472870278712053782e+00, -6.294183498489253070e-02,
      4.769273959660644442e-03,  8.414681093302789892e-05,
      -1.142905205912834352e-05, -4.014065121916994726e-06,
      6.349296248136164778e-01,  1.440137170869312810e-03,
      6.346663352465874847e-03,  -2.133510744796659759e-04,
      -1.788513201196447670e-04, 1.721163944875696416e-05,
      -1.321968230245579967e+00, -5.421934303028537461e-02,
      1.257335706466754244e-02,  -7.282542863230233527e-04,
      -1.343059033644905889e-04, 1.747822893445653714e-05,
      -9.941857609618123259e-01, 6.848272942128874607e-02,
      -5.019121140152461337e-03, -1.683596869525186377e-04,
      1.024142382012053007e-04,  -2.632719129544749384e-05,
      3.523983851077774343e-01,  -3.597488523292310947e-02,
      -1.080005278271846739e-03, 9.827512175914082399e-04,
      -1.066680880078371994e-04, 3.403258606315080555e-07,
      1.231053381658700818e+00,  4.156889948792314576e-02,
      3.478797077596604108e-03,  -4.696409807358484993e-04,
      -1.173636798436718986e-04, 1.149931408689037458e-05,
      -1.485427934690428442e+00, -1.584992071496764965e-01,
      1.649651778315383566e-02,  1.415960091521040870e-04,
      -2.125888038426753843e-04, 7.384582528889821378e-06,
      -2.777120456109742896e-01, 9.738715268720327112e-02,
      -2.311658999267464203e-03, -7.080165982958596923e-04,
      2.340034491729013294e-05,  5.174033942788913380e-06,
      -1.473499220050474623e+00, -6.284642430757329812e-02,
      4.771791466347353149e-03,  8.368540130389298475e-05,
      -1.162498575113560591e-05, -5.381585801785509468e-06,
      6.349446606365225509e-01,  1.567005718051586727e-03,
      6.340155681555815353e-03,  -2.204854663573854625e-04,
      -1.779502948888764897e-04, 3.196283450610521294e-05,
      -1.322509167069771951e+00, -5.396809490162747525e-02,
      1.255142902735281209e-02,  -7.336077414823606981e-04,
      -1.332538502428148267e-04, 2.525523713666122703e-05,
      -9.935014357470516311e-01, 6.838229689892011409e-02,
      -5.024110745516051704e-03, -1.642860423419652261e-04,
      1.011792892256958577e-04,  -5.902237032851650630e-06,
      3.520385292366049468e-01,  -3.599619093977864809e-02,
      -1.050586739210998023e-03, 9.784837539753422735e-04,
      -1.066187407206570670e-04, -6.052991441884039902e-06,
      1.231469418062474341e+00,  4.163833406830096812e-02,
      3.464637544942418459e-03,  -4.743218246565151001e-04,
      -1.164951133813105271e-04, 2.473911917278243621e-05,
      -1.487011276970676033e+00, -1.581692351651968476e-01,
      1.650063818395723983e-02,  1.331001312464952355e-04,
      -2.118074389246019866e-04, 9.192428068946771109e-06,
      -2.767384059577842614e-01, 9.734070719609828892e-02,
      -2.332885405321092481e-03, -7.070743922828596519e-04,
      2.373777250910882265e-05,  1.127700884024945933e-05,
      -1.474127207030835107e+00, -6.275096341939470634e-02,
      4.774294999622533293e-03,  8.321347296773265077e-05,
      -1.162225195759229858e-05, -1.468175407624093560e-05,
      6.349609644870094494e-01,  1.693741975839754832e-03,
      6.333434667015966531e-03,  -2.275719866012916918e-04,
      -1.766077012712487378e-04, 2.919052022666632077e-05,
      -1.323047593610823247e+00, -5.371728693515605280e-02,
      1.252934109528984138e-02,  -7.389107006611626187e-04,
      -1.322992615601379437e-04, 3.689337377145077536e-05,
      -9.928181153524118230e-01, 6.828176580261838269e-02,
      -5.028978678356570489e-03, -1.602449667799085492e-04,
      1.004819833385002965e-04,  -7.012859043909368637e-06,
      3.516784632459502014e-01,  -3.601690955621394963e-02,
      -1.021296258318379370e-03, 9.742140050919662845e-04,
      -1.068837890347894775e-04, 3.261791903209577241e-07,
      1.231886147391427544e+00,  4.170748405790913882e-02,
      3.450338240560582581e-03,  -4.789562532735843967e-04,
      -1.153902983973557932e-04, 2.856018069496295048e-05,
      -1.488591319127526624e+00, -1.578391833182464787e-01,
      1.650450419566778376e-02,  1.246407552546250339e-04,
      -2.115332183818513349e-04, 3.149345367837511192e-05,
      -2.757652328811996956e-01, 9.729383746118988596e-02,
      -2.354083281534554220e-03, -7.061133365182417328e-04,
      2.418809213597686327e-05,  1.280494807360028992e-05,
      -1.474754239152433311e+00, -6.265545260258377491e-02,
      4.776784283590801948e-03,  8.273687806363864625e-05,
      -1.229952261449745124e-05, 3.204146150058887708e-06,
      6.349785350208994039e-01,  1.820341692612803541e-03,
      6.326501834700739083e-03,  -2.346100929840904846e-04,
      -1.748840426396014729e-04, 1.130785525935554482e-05,
      -1.323583514286295282e+00, -5.346692231381247606e-02,
      1.250709476370755191e-02,  -7.441705970339035966e-04,
      -1.303302437099287372e-04, 7.935577538626925858e-06,
      -9.921358007514943234e-01, 6.818113855713830995e-02,
      -5.033725808341922223e-03, -1.562353718150353687e-04,
      1.001568149392305130e-04,  -2.302258383924021595e-05,
      3.513181929939074299e-01,  -3.603704364469759169e-02,
      -9.921339651685744804e-04, 9.699384566370250092e-04,
      -1.069081013817698415e-04, -2.744679484186812129e-06,
      1.232303566785723392e+00,  4.177634667571154814e-02,
      3.435900604437185177e-03,  -4.835440426346156498e-04,
      -1.140781768005934266e-04, 2.411509316948267986e-05,
      -1.490168060387760951e+00, -1.575090566866652331e-01,
      1.650811681325956015e-02,  1.162064642248029450e-04,
      -2.100324946396962247e-04, 4.868837971279583202e-06,
      -2.747925306207861240e-01, 9.724654405895133413e-02,
      -2.375252040655950400e-03, -7.051355614741510987e-04,
      2.505903781065493165e-05,  -2.569082101323676566e-06,
      -1.475380315917416585e+00, -6.255989214488603956e-02,
      4.779259042312647421e-03,  8.224491253736542200e-05,
      -1.205054378062991984e-05, -1.594987943813344381e-05,
      6.349973708516511994e-01,  1.946800647308156995e-03,
      6.319358714566076195e-03,  -2.415904693897710526e-04,
      -1.741570105122868483e-04, 3.342152683043006766e-05,
      -1.324116933545430141e+00, -5.321700419064152865e-02,
      1.248469152702344660e-02,  -7.493727578058629766e-04,
      -1.295525827398787404e-04, 2.659942231629285135e-05,
      -9.914544928937398804e-01, 6.808041756983601589e-02,
      -5.038353005641925050e-03, -1.522500103683389601e-04,
      9.911425811568465554e-05,  -1.035676665958809070e-05,
      3.509577243129330393e-01,  -3.605659577023319351e-02,
      -9.630999837076988784e-04, 9.656594578503095369e-04,
      -1.070158919994286978e-04, -2.281503112307771063e-06,
      1.232721673357858538e+00,  4.184491916948063911e-02,
      3.421326077437690516e-03,  -4.880823132679394552e-04,
      -1.129872290747681817e-04, 2.854952342195995698e-05,
      -1.491741500028839651e+00, -1.571788603283475749e-01,
      1.651147703627379656e-02,  1.078118218043548068e-04,
      -2.094656285123614196e-04, 1.573608604543182341e-05,
      -2.738203034102859035e-01, 9.719882757757769554e-02,
      -2.396391097750961291e-03, -7.041328812172977002e-04,
      2.511128111671661627e-05,  1.472819566023977703e-05,
      -1.476005436830838402e+00, -6.246428233956573262e-02,
      4.781718999863710830e-03,  8.175246233396933941e-05,
      -1.310850420537104008e-05, 1.717274673157189222e-05,
      6.350174705506670403e-01,  2.073114649501703322e-03,
      6.312006840494438151e-03,  -2.485262001215581039e-04,
      -1.724445833892894095e-04, 1.623821996891234705e-05,
      -1.324647855868849478e+00, -5.296753568880858964e-02,
      1.246213287875118370e-02,  -7.545274547770323926e-04,
      -1.284298383236558551e-04, 3.142127009671183137e-05,
      -9.907741927046019859e-01, 6.797960523066012839e-02,
      -5.042861140826992473e-03, -1.482946605870891395e-04,
      9.821987974303589589e-05,  -3.593831829470692349e-06,
      3.505970630098214080e-01,  -3.607556850024738748e-02,
      -9.341944322877257512e-04, 9.613773761737330267e-04,
      -1.072343182304808093e-04, 2.791451096706449119e-06,
      1.233140464192951757e+00,  4.191319881581374862e-02,
      3.406616101162745613e-03,  -4.925758895926437772e-04,
      -1.113902906060245713e-04, 1.275308331152581608e-05,
      -1.493311637378700762e+00, -1.568485992811522733e-01,
      1.651458586873823589e-02,  9.944841367174414462e-05,
      -2.085492230796830474e-04, 1.276456024245067926e-05,
      -2.728485554775001987e-01, 9.715068861693920699e-02,
      -2.417499870240937074e-03, -7.031148500958378164e-04,
      2.576543833825076558e-05,  7.841889896124507091e-06,
      -1.476629601400710978e+00, -6.236862348540499201e-02,
      4.784163880393361643e-03,  8.124213252544174404e-05,
      -1.286332078849730127e-05, -1.821996546344873330e-06,
      6.350388326475970846e-01,  2.199279539485121671e-03,
      6.304447750121061969e-03,  -2.554047701160370044e-04,
      -1.716061813901302753e-04, 3.413524324276134592e-05,
      -1.325176285768258300e+00, -5.271851990161838253e-02,
      1.243942031140890699e-02,  -7.596346042592860793e-04,
      -1.269803855069738714e-04, 2.314478643438959578e-05,
      -9.900949010857222898e-01, 6.787870391214460841e-02,
      -5.047251084767826433e-03, -1.443753107913585767e-04,
      9.837034053479728221e-05,  -3.865274593462701621e-05,
      3.502362148656810170e-01,  -3.609396440447816545e-02,
      -9.054174237006253068e-04, 9.570894530963515055e-04,
      -1.071221722792567601e-04, -5.180134097885568801e-06,
      1.233559936349031494e+00,  4.198118292014653419e-02,
      3.391772117805412056e-03,  -4.970162819604460663e-04,
      -1.105584293158747960e-04, 2.757032189173095048e-05,
      -1.494878471815561216e+00, -1.565182785628131401e-01,
      1.651744431908664865e-02,  9.112268062696188113e-05,
      -2.082277461664644284e-04, 3.370820636496137736e-05,
      -2.718772910441742408e-01, 9.710212778853387350e-02,
      -2.438577777940475859e-03, -7.020756635958485484e-04,
      2.613933618298708639e-05,  1.211520684095310762e-05,
      -1.477252809138063672e+00, -6.227291588670166161e-02,
      4.786593408182711167e-03,  8.072392747742672100e-05,
      -1.281499371544444526e-05, -1.293175202324119235e-05,
      6.350614556306495295e-01,  2.325291188338546311e-03,
      6.296682984661446623e-03,  -2.622362895631248896e-04,
      -1.701076322674243866e-04, 2.573454296903621253e-05,
      -1.325702227786145437e+00, -5.246995989253622206e-02,
      1.241655531642829255e-02,  -7.646904682589584622e-04,
      -1.257704658362481128e-04, 2.439373356208127567e-05,
      -9.894166189151047952e-01, 6.777771596940393439e-02,
      -5.051523708536139086e-03, -1.404733355821404265e-04,
      9.677082285072928253e-05,  -3.720510878458014501e-06,
      3.498751856359115786e-01,  -3.611178605486395354e-02,
      -8.767690652124425499e-04, 9.527998576480508275e-04,
      -1.072771816869139909e-04, -2.281376475091892258e-06,
      1.233980086857325631e+00,  4.204886881676297983e-02,
      3.376795570009583514e-03,  -5.014114486109571937e-04,
      -1.092957353261917852e-04, 2.516456964431257380e-05,
      -1.496442002767713664e+00, -1.561879031708521548e-01,
      1.652005340007862977e-02,  8.282284133744905071e-05,
      -2.067123325224875000e-04, 7.057486539657783089e-06,
      -2.709065143258797548e-01, 9.705314571543909030e-02,
      -2.459624243094573216e-03, -7.010187162791577066e-04,
      2.672975399789282626e-05,  7.629793933874534523e-06,
      -1.477875059556995385e+00, -6.217715985326619649e-02,
      4.789007307701962507e-03,  8.019935829649041371e-05,
      -1.318861260046749971e-05, -7.150339348059032240e-06,
      6.350853379468965887e-01,  2.451145498001100487e-03,
      6.288714088740080324e-03,  -2.690159202421790068e-04,
      -1.686584359429067433e-04, 1.941481480743946700e-05,
      -1.326225686495484890e+00, -5.222185869521017709e-02,
      1.239353938406437261e-02,  -7.696964132049412353e-04,
      -1.246012242240120604e-04, 2.724071141974432252e-05,
      -9.887393470472876089e-01, 6.767664374012982709e-02,
      -5.055679883306329545e-03, -1.366074591188833347e-04,
      9.623033677044332457e-05,  -1.113456896173822779e-05,
      3.495139810501832756e-01,  -3.612903602543367232e-02,
      -8.482494585971035728e-04, 9.485064841097947883e-04,
      -1.073561607316583907e-04, -2.239996380309942211e-06,
      1.234400912722548371e+00,  4.211625386880359784e-02,
      3.361687900729734210e-03,  -5.057597926077623488e-04,
      -1.078411892315765344e-04, 1.508800592977199686e-05,
      -1.498002229713325750e+00, -1.558574780824932282e-01,
      1.652241412871961052e-02,  7.456368677257522147e-05,
      -2.062001731191939454e-04, 2.069621557469772063e-05,
      -2.699362295319003291e-01, 9.700374303226286243e-02,
      -2.480638690415259105e-03, -6.999405672986690023e-04,
      2.700789474676622474e-05,  1.556143061449123430e-05,
      -1.478496352174730522e+00, -6.208135570041733303e-02,
      4.791405303667145565e-03,  7.966538051836852740e-05,
      -1.352687841609079228e-05, -2.789411930543395566e-06,
      6.351104780025849106e-01,  2.576838401336829787e-03,
      6.280542610220480118e-03,  -2.757414391158645754e-04,
      -1.675762649448408429e-04, 2.787462665161048641e-05,
      -1.326746666499438287e+00, -5.197421931349595348e-02,
      1.237037400330611749e-02,  -7.746541492504023475e-04,
      -1.232228491818352083e-04, 2.166599538617633252e-05,
      -9.880630863135209108e-01, 6.757548954459043078e-02,
      -5.059720480258220535e-03, -1.327693574508429343e-04,
      9.550030312894054513e-05,  -1.096549240339310371e-05,
      3.491526068124157778e-01,  -3.614571689219699124e-02,
      -8.198587001702131727e-04, 9.442100079790295610e-04,
      -1.074330339280879455e-04, -2.103241190440061311e-06,
      1.234822410923189784e+00,  4.218333546826981417e-02,
      3.346450553092000530e-03,  -5.100549148199152614e-04,
      -1.071543306169886722e-04, 3.572075491055831030e-05,
      -1.499559152180234056e+00, -1.555270082545787691e-01,
      1.652452752618108200e-02,  6.633607063542407416e-05,
      -2.052990867644106118e-04, 1.891505702101457936e-05,
      -2.689664408651156746e-01, 9.695392038509384469e-02,
      -2.501620547117759490e-03, -6.988464710389351081e-04,
      2.774961528830105395e-05,  4.843681010028069226e-06,
      -1.479116686511674494e+00, -6.198550374897651011e-02,
      4.793787121096219732e-03,  7.912045955652986253e-05,
      -1.359696279035538403e-05, -9.132339849453571562e-06,
      6.351368741634448867e-01,  2.702365862198193025e-03,
      6.272170100036473551e-03,  -2.824171711189519380e-04,
      -1.661976899287730559e-04, 2.457347650017094835e-05,
      -1.327265172431057128e+00, -5.172704472148267896e-02,
      1.234706066178771662e-02,  -7.795630288411945592e-04,
      -1.217395799935142969e-04, 1.184741714306808905e-05,
      -9.873878375219384829e-01, 6.747425568563097942e-02,
      -5.063646370480812467e-03, -1.289626891970745083e-04,
      9.513074838211379970e-05,  -2.521433322545949321e-05,
      3.487910686007592576e-01,  -3.616183123303555458e-02,
      -7.915968808226425679e-04, 9.399119246579864433e-04,
      -1.077055728285351480e-04, 6.031191175422362627e-06,
      1.235244578411804905e+00,  4.225011103602600848e-02,
      3.331084970256580589e-03,  -5.143079026275864784e-04,
      -1.055716785023949844e-04, 2.051193936812822612e-05,
      -1.501112769745742259e+00, -1.551964986234863897e-01,
      1.652639461772111712e-02,  5.814089462644928566e-05,
      -2.041249358339155683e-04, 6.311073191969795411e-06,
      -2.679971525218879380e-01, 9.690367843145115956e-02,
      -2.522569242956208650e-03, -6.977319783847560700e-04,
      2.827424678587480721e-05,  2.739673941330651616e-06,
      -1.479736062091468574e+00, -6.188960432526132566e-02,
      4.796152485364500034e-03,  7.856828747830194362e-05,
      -1.395147193446202365e-05, -4.087221013031299888e-06,
      6.351645247550001816e-01,  2.827723875485507743e-03,
      6.263598112024793517e-03,  -2.890409134869928735e-04,
      -1.648390823803598971e-04, 2.215887759642637032e-05,
      -1.327781208952985015e+00, -5.148033786352124164e-02,
      1.232360084570068709e-02,  -7.844171563535663055e-04,
      -1.210428935521009746e-04, 3.344327592646507844e-05,
      -9.867136014577331249e-01, 6.737294444867666932e-02,
      -5.067458424877044516e-03, -1.251812701937470213e-04,
      9.419473244264059593e-05,  -1.679002076268449654e-05,
      3.484293720675762929e-01,  -3.617738162759492893e-02,
      -7.634640860539731316e-04, 9.356082122653546981e-04,
      -1.075431084112703954e-04, -3.044614041061100766e-06,
      1.235667412115300623e+00,  4.231657802179918798e-02,
      3.315592595281378029e-03,  -5.185116053649769336e-04,
      -1.041674655671950871e-04, 1.242766263135090892e-05,
      -1.502663082036415076e+00, -1.548659541050484978e-01,
      1.652801643260504508e-02,  4.998556989557471122e-05,
      -2.037688261998792680e-04, 2.657243869390409541e-05,
      -2.670283686919466826e-01, 9.685301784023310490e-02,
      -2.543484210258855835e-03, -6.965966582328896994e-04,
      2.850491087748043708e-05,  1.232179636112698650e-05,
      -1.480354478441044286e+00, -6.179365776107784841e-02,
      4.798501122259496952e-03,  7.800586916120723585e-05,
      -1.413851691566035862e-05, -5.727587674967719880e-06,
      6.351934280628791507e-01,  2.952908467203564646e-03,
      6.254828202758994093e-03,  -2.956111985445306826e-04,
      -1.636502852942454153e-04, 2.616921494951480123e-05,
      -1.328294780757159899e+00, -5.123410165425365537e-02,
      1.229999603970671068e-02,  -7.892274520450543677e-04,
      -1.195721301312790567e-04, 2.454197033093738297e-05,
      -9.860403788833298488e-01, 6.727155810173718331e-02,
      -5.071157514069617352e-03, -1.214296539729165295e-04,
      9.340570341953608358e-05,  -1.444050153586573228e-05,
      3.480675228394242149e-01,  -3.619237065717702262e-02,
      -7.354603960058733389e-04, 9.313051737393654526e-04,
      -1.076930273455606579e-04, -7.696053039474192446e-07,
      1.236090908935226107e+00,  4.238273390417521269e-02,
      3.299974870987111650e-03,  -5.226642260988254756e-04,
      -1.032474625011560351e-04, 2.396475265799989632e-05,
      -1.504210088727871764e+00, -1.545353795944727493e-01,
      1.652939400402650763e-02,  4.186078937618800693e-05,
      -2.027012231708198600e-04, 1.761148452766873776e-05,
      -2.660600935582757565e-01, 9.680193929166537592e-02,
      -2.564364883962782712e-03, -6.954454205710857090e-04,
      2.907017700829073683e-05,  9.120785771591908463e-06,
      -1.480971935090678926e+00, -6.169766439371183325e-02,
      4.800832758035045861e-03,  7.743502257440657043e-05,
      -1.440171540732098418e-05, -4.489324897938611976e-06,
      6.355509554770921721e-01,  4.194364255265300989e-03,
      6.156587518227093006e-03,  -3.584539136959086518e-04,
      -1.505562336471176987e-04, 2.631189526673375584e-05,
      -1.333295991901433553e+00, -4.879824528740911438e-02,
      1.205629889598585497e-02,  -8.346035033896359156e-04,
      -1.072962342948566929e-04, 2.412331753624817981e-05,
      -9.793640468817854661e-01, 6.625405011186732973e-02,
      -5.102126473064734317e-03, -8.551069374443776396e-05,
      8.618032279329005427e-05,  -1.422030758858379208e-05,
      3.444418516979214084e-01,  -3.631195473807800889e-02,
      -4.625381215785304145e-04, 8.881537622047225473e-04,
      -1.080757789189670570e-04, 5.820590714360855199e-08,
      1.240361649325028681e+00,  4.302664794411619614e-02,
      3.137220402938139478e-03,  -5.615677039256951981e-04,
      -9.125763978623760322e-05, 2.367398552885374808e-05,
      -1.519498310980496925e+00, -1.512290469691385253e-01,
      1.652996628226939199e-02,  -3.745688059096337011e-05,
      -1.938906911473592626e-04, 1.811217640451412989e-05,
      -2.564062357251438717e-01, 9.626832379335603651e-02,
      -2.771163091665611831e-03, -6.829069315554202020e-04,
      3.363238372709415958e-05,  8.623099725596635004e-06,
      -1.487093617252511990e+00, -6.073523464295225993e-02,
      4.823154268625621383e-03,  7.122599345182346051e-05,
      -1.664931178025436733e-05, -4.312450972708557703e-06};
  std::vector<double> expected_xyz_scatter = {
      0.634877,  -1.319469, -0.997320, 0.354037,  1.229165,  -1.478165,
      -0.282159, -1.470623, 0.634985,  -1.323774, -0.991892, 0.351189,
      1.232453,  -1.490731, -0.274445, -1.475604, 0.634938,  -1.322286,
      -0.993784, 0.352187,  1.231297,  -1.486357, -0.277141, -1.473868,
      0.635174,  -1.327955, -0.986486, 0.348307,  1.235810,  -1.503186,
      -0.266701, -1.480563, 0.635175,  -1.327965, -0.986473, 0.348300,
      1.235819,  -1.503216, -0.266682, -1.480575, 0.634890,  -1.320208,
      -0.996398, 0.353557,  1.229717,  -1.480303, -0.280853, -1.471469,
      0.634902,  -1.320794, -0.995664, 0.353173,  1.230159,  -1.482005,
      -0.279812, -1.472143, 0.635167,  -1.327823, -0.986659, 0.348400,
      1.235701,  -1.502788, -0.266950, -1.480404, 0.635088,  -1.326284,
      -0.988664, 0.349474,  1.234448,  -1.498176, -0.269828, -1.478565,
      0.634918,  -1.321522, -0.994748, 0.352694,  1.230712,  -1.484126,
      -0.278511, -1.472983, 0.634962,  -1.323089, -0.992765, 0.351650,
      1.231919,  -1.488714, -0.275689, -1.474803, 0.634888,  -1.320133,
      -0.996492, 0.353606,  1.229661,  -1.480085, -0.280986, -1.471383,
      0.634968,  -1.323280, -0.992522, 0.351522,  1.232067,  -1.489275,
      -0.275344, -1.475026, 0.635077,  -1.326043, -0.988976, 0.349640,
      1.234254,  -1.497458, -0.270275, -1.478280, 0.635124,  -1.327021,
      -0.987707, 0.348962,  1.235045,  -1.500380, -0.268455, -1.479444,
      0.634885,  -1.319917, -0.996762, 0.353746,  1.229499,  -1.479460,
      -0.281368, -1.471135};
  std::vector<double> expected_dy_dem = {
      -0.105883, -0.100297, -0.102247, -0.094712, -0.094698, -0.104937,
      -0.104182, -0.094891, -0.096964, -0.103240, -0.101197, -0.105033,
      -0.100947, -0.097286, -0.095974, -0.105310};

  const int nloc = 4;
  const int nnei = 4;
  const int last_layer_size = 8;

  void SetUp() override {}
  void TearDown() override {}
};

TEST_F(TestTabulateSeR, tabulate_fusion_se_r_cpu) {
  std::vector<double> xyz_scatter(nloc * nnei * last_layer_size);
  deepmd::tabulate_fusion_se_r_cpu<double>(&xyz_scatter[0], &table[0], &info[0],
                                           &em[0], nloc, nnei, last_layer_size);
  EXPECT_EQ(xyz_scatter.size(), nloc * nnei * last_layer_size);
  EXPECT_EQ(xyz_scatter.size(), expected_xyz_scatter.size());
  for (int jj = 0; jj < xyz_scatter.size(); ++jj) {
    EXPECT_LT(fabs(xyz_scatter[jj] - expected_xyz_scatter[jj]), 1e-5);
  }
}

TEST_F(TestTabulateSeR, tabulate_fusion_se_r_grad_cpu) {
  std::vector<double> dy_dem(em.size());
  std::vector<double> dy(nloc * nnei * last_layer_size, 1.0);
  deepmd::tabulate_fusion_se_r_grad_cpu<double>(&dy_dem[0], &table[0], &info[0],
                                                &em[0], &dy[0], nloc, nnei,
                                                last_layer_size);
  EXPECT_EQ(dy_dem.size(), nloc * nnei);
  EXPECT_EQ(dy_dem.size(), expected_dy_dem.size());
  for (int jj = 0; jj < dy_dem.size(); ++jj) {
    EXPECT_LT(fabs(dy_dem[jj] - expected_dy_dem[jj]), 1e-5);
  }
}

#if GOOGLE_CUDA || TENSORFLOW_USE_ROCM
TEST_F(TestTabulateSeR, tabulate_fusion_se_r_gpu) {
  std::vector<double> xyz_scatter(nloc * nnei * last_layer_size, 0.0);

  double *xyz_scatter_dev = NULL, *table_dev = NULL, *em_dev = NULL;
  deepmd::malloc_device_memory_sync(xyz_scatter_dev, xyz_scatter);
  deepmd::malloc_device_memory_sync(table_dev, table);
  deepmd::malloc_device_memory_sync(em_dev, em);
  deepmd::tabulate_fusion_se_r_gpu<double>(xyz_scatter_dev, table_dev, &info[0],
                                           em_dev, nloc, nnei, last_layer_size);
  deepmd::memcpy_device_to_host(xyz_scatter_dev, xyz_scatter);
  deepmd::delete_device_memory(xyz_scatter_dev);
  deepmd::delete_device_memory(table_dev);
  deepmd::delete_device_memory(em_dev);

  EXPECT_EQ(xyz_scatter.size(), nloc * nnei * last_layer_size);
  EXPECT_EQ(xyz_scatter.size(), expected_xyz_scatter.size());
  for (int jj = 0; jj < xyz_scatter.size(); ++jj) {
    EXPECT_LT(fabs(xyz_scatter[jj] - expected_xyz_scatter[jj]), 1e-5);
  }
}

TEST_F(TestTabulateSeR, tabulate_fusion_se_r_grad_gpu) {
  std::vector<double> dy_dem(em.size(), 0.0);
  std::vector<double> dy(nloc * nnei * last_layer_size, 1.0);

  double *dy_dem_dev = NULL, *table_dev = NULL, *em_dev = NULL, *dy_dev = NULL;
  deepmd::malloc_device_memory_sync(dy_dem_dev, dy_dem);
  deepmd::malloc_device_memory_sync(table_dev, table);
  deepmd::malloc_device_memory_sync(em_dev, em);
  deepmd::malloc_device_memory_sync(dy_dev, dy);
  deepmd::tabulate_fusion_se_r_grad_gpu<double>(dy_dem_dev, table_dev, &info[0],
                                                em_dev, dy_dev, nloc, nnei,
                                                last_layer_size);
  deepmd::memcpy_device_to_host(dy_dem_dev, dy_dem);
  deepmd::delete_device_memory(dy_dem_dev);
  deepmd::delete_device_memory(table_dev);
  deepmd::delete_device_memory(em_dev);
  deepmd::delete_device_memory(dy_dev);

  EXPECT_EQ(dy_dem.size(), nloc * nnei);
  EXPECT_EQ(dy_dem.size(), expected_dy_dem.size());

  for (int jj = 0; jj < dy_dem.size(); ++jj) {
    EXPECT_LT(fabs(dy_dem[jj] - expected_dy_dem[jj]), 1e-5);
  }
}
#endif  // GOOGLE_CUDA || TENSORFLOW_USE_ROCM
